import NProgress from 'nprogress'
import axios from 'axios'
import router from '@/router'
import AxiosRequest, { axiosErrorIs } from './request'
import defaultSettings from '@/settings'
// import { getToken } from '@/utils/auth'
import { encryptionParams } from './encryptionTool'
import { useAppStore } from '@/store/index'
import { useErrorMessage } from '@/hooks/message'

import type { RequestOptions } from './types'

const { baseURL, timeout, TokenKey, encryptable } = defaultSettings

// 获取 headers
const getHeaders: any = () => {
	const appStore = useAppStore()
	return {
		[TokenKey]: appStore.token || '',
	}
}

let loadingInstance: any = null
const { isCancel } = axios

const instance = new AxiosRequest({
	baseURL,
	timeout,
	beforeRequest(config) {
		NProgress.start()

		if (config.loading) {
			loadingInstance = ElLoading.service({ fullscreen: true, lock: true, background: 'rgba(158, 158, 158, 0.3)', text: '加载中...' })
		}
		config.encryptable = encryptable // 是否加密
		console.log('beforeRequest----1', getHeaders())
		config = encryptionParams(config)
		instance.setHeader(getHeaders())
		return config
	},
	afterResponseThen(response, baseConfig) {
		const appStore = useAppStore()
		const data = response.data
		const { isReturnNativeResponse } = baseConfig

		// console.log('baseConfig---', response, baseConfig)
		if (isReturnNativeResponse) return Promise.resolve(response)

		if (data.code >= 5000 && data.code < 6000) {
			data.msg && useErrorMessage(data.msg)
			if (data.code == 5001) {
				appStore.$reset()
				router.replace('/login')
			}
			return Promise.reject(response)
		}

		if (data.code == 1 || data.code == 200) {
			data.data === null && console.warn(data)
			return Promise.resolve(data)
		}
		data.msg && useErrorMessage(data.msg)
		return Promise.reject(response)
	},
	afterResponseCatch(error) {
		console.log('afterResponseCatch---', error)
		if (!axiosErrorIs(error)) return error

		if (error.message && error.message.indexOf('timeout') !== -1) {
			// 超时
			error.message = '请求超时'
		}
		// 过期
		if (error.response?.data && error.response.data.code === 5001) {
			// pinia.useAppStore.refreshToken()
		}
		// showCatchErrorMessage
		// if(!isCancel){

		// }
		// !isCancel(error) &&
		error.message && useErrorMessage(error.message)
		return error
	},
	afterResponseFinally() {
		NProgress.done()
		setTimeout(() => loadingInstance && loadingInstance.close(), 160)
	},
	// transformRequest: [
	// 	function (data, headers) {
	// 		NProgress.start()
	// 		// 对接收的 data 进行任意转换处理
	// 		console.log('transformRequest', data, headers)
	// 		return qs.stringify(data, { arrayFormat: 'brackets' })
	// 	},
	// ],
	// transformResponse: function (data) {
	// 	NProgress.done()
	// 	// 对接收的 data 进行任意转换处理
	// 	// console.log('transformResponse：', JSON.parse(data))
	// 	return JSON.parse(data)
	// },
})

/**
 * 发起GET请求
 *
 * @param url 请求的URL地址
 * @param params 请求参数
 * @param options 请求配置，包含headers等信息，部分RequestOptions类型
 * @returns 请求响应的数据
 * @template T 返回的数据类型，默认为any
 * @template U 请求参数类型，默认为any
 */
const get = <T = any, U = any, P extends RequestOptions = RequestOptions>(url: string, params: U, options: P) => {
	return instance.request<U, T>({
		...options,
		url,
		params,
		method: 'get',
	})
}

/**
 * 发送 POST 请求
 *
 * @param url 请求地址
 * @param data 请求数据
 * @param options 请求选项（可选）
 * @returns 响应数据
 */
const post = <T = any, U = any, P extends RequestOptions = RequestOptions>(url: string, data: U, options: P) => {
	return instance.request<U, T>({
		...options,
		url,
		data,
		method: 'post',
	})
}

// 上传
const uploadFile = <T = any, U = any>(url: string, data: T = {} as T, method = 'post') => {
	return instance.request<T, U>({
		url,
		data,
		method,
		headers: {
			'Content-Type': 'multipart/form-data',
		},
	})
}

// 导出文件
const exportFile = <T = any, D extends Blob = Blob>(url: string, data, method = 'post', names?: string) => {
	data = { ...data, loading: true }
	return instance.request<T, D>({
		url,
		data: method === 'post' ? data : void 0,
		params: method === 'get' ? data : void 0,
		method,
		responseType: 'blob',
		async afterResponseThen(response) {
			// console.log('afterResponseThen--', response)
			const data = response.data
			try {
				if (data.type === 'text/html') {
					const enc = new TextDecoder('utf-8')
					const buffer = await data.arrayBuffer()
					const result = JSON.parse(enc.decode(new Uint8Array(buffer))) || { code: 555, message: '未知' }
					return Promise.reject({ ...result, message: result.message || result.msg })
				} else if (data.type === 'application/octet-stream') {
					const headers = response.headers
					const fileNameEncode = headers['content-disposition']?.split(';')[1].split('filename=')[1]
					const fileName = decodeURI(fileNameEncode || '')
					const blob = new Blob([data])
					const downloadElement = document.createElement('a')
					const href = window.URL.createObjectURL(blob) //创建下载的链接
					// console.log('names', names, fileName)
					downloadElement.href = href
					downloadElement.download = names ? names : fileName //下载后文件名
					document.body.appendChild(downloadElement)
					downloadElement.click() //	点击下载
					document.body.removeChild(downloadElement) //下载完成移除元素
					window.URL.revokeObjectURL(href) //释放掉blob对象
					// console.log('response---', response)
					// return Promise.resolve({ data, fileName, code: response.status })
				}
				return Promise.resolve(response)
			} catch (error) {
				// return Promise.reject({ data, fileName: '', code: 400, error: error })
				return Promise.reject(error)
			}
		},
	})
}

// 取消请求
// const cancelRequest = (url: string | string[]) => instance.cancelRequest(url)

// 取消全部请求
// const cancelAllRequest = () => instance.cancelAllRequest()

const request = instance.request

export { getHeaders, get, post, uploadFile, exportFile, request }
export default instance
